#include "richtextedit.h"

RichTextEdit::RichTextEdit(QWidget *parent) : QTextEdit(parent)
	{
		toolbar = new QToolBar(this);
		toolbar->setIconSize(QSize(20,20));

		fontBox = new QFontComboBox(this);
		connect(fontBox, SIGNAL(activated(QString)), this, SLOT(setFontFamily(QString)));

		sizeBox = new QComboBox(this);
		sizeBox->setEditable(true);
		foreach(int s, QFontDatabase::standardSizes())
			sizeBox->addItem(QString::number(s));
		connect(sizeBox, SIGNAL(activated(QString)), this, SLOT(setFontSize(QString)));

		timer = new QTimer(this);
		timer->setInterval(850);

		leftAlignAction = new QAction(QIcon(":/icons/format-justify-left.png"), tr("Left Align"), this);
		leftAlignAction->setCheckable(true);
		leftAlignAction->setShortcut(QKeySequence("Ctrl+Alt+L"));
		toolbar->addAction(leftAlignAction);

		centerAlignAction = new QAction(QIcon(":/icons/format-justify-center.png"), tr("Center Align"), this);
		centerAlignAction->setCheckable(true);
		centerAlignAction->setShortcut(QKeySequence("Ctrl+Alt+C"));
		toolbar->addAction(centerAlignAction);

		rightAlignAction = new QAction(QIcon(":/icons/format-justify-right.png"), tr("Right Align"), this);
		rightAlignAction->setCheckable(true);
		rightAlignAction->setShortcut(QKeySequence("Ctrl+Alt+R"));
		toolbar->addAction(rightAlignAction);

		justifyAction = new QAction(QIcon(":/icons/format-justify-fill.png"), tr("Justify"), this);
		justifyAction->setCheckable(true);
		justifyAction->setShortcut(QKeySequence("Ctrl+Alt+J"));
		toolbar->addAction(justifyAction);
		toolbar->addSeparator();

		boldAction = new QAction(QIcon(":/icons/format-text-bold.png"), tr("Bold"), this);
		boldAction->setCheckable(true);
		boldAction->setShortcut(QKeySequence("Ctrl+B"));
		connect(boldAction, SIGNAL(triggered(bool)), this, SLOT(setBold(bool)));
		toolbar->addAction(boldAction);

		italicAction = new QAction(QIcon(":/icons/format-text-italic.png"), tr("Italic"), this);
		italicAction->setCheckable(true);
		italicAction->setShortcut(QKeySequence("Ctrl+I"));
		connect(italicAction, SIGNAL(triggered(bool)), this, SLOT(setFontItalic(bool)));
		toolbar->addAction(italicAction);

		underlineAction = new QAction(QIcon(":/icons/format-text-underline.png"), tr("Underline"), this);
		underlineAction->setCheckable(true);
		underlineAction->setShortcut(QKeySequence("Ctrl+U"));
		connect(underlineAction, SIGNAL(triggered(bool)), this, SLOT(setFontUnderline(bool)));
		toolbar->addAction(underlineAction);
		toolbar->addSeparator();

		toolbar->addWidget(fontBox);
		toolbar->addWidget(sizeBox);
		toolbar->addSeparator();

		colorPickerAction = new QAction(QIcon(":/icons/format-text-color.png"), tr("Choose Color"), this);
		connect(colorPickerAction, SIGNAL(triggered()), this, SLOT(setColor()));
		toolbar->addAction(colorPickerAction);

		alignGroup = new QActionGroup(this);
		alignGroup->addAction(leftAlignAction);
		alignGroup->addAction(centerAlignAction);
		alignGroup->addAction(rightAlignAction);
		alignGroup->addAction(justifyAction);
		connect(alignGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeAlignment(QAction*)));

		setViewportMargins(0, toolbar->sizeHint().height()-5, 0, 0);
		setContentsMargins(0, toolbar->sizeHint().height(), 0, 0);

		connect(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(updateCharFormat(QTextCharFormat)));
		connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateBlockFormat()));

		connect(this, SIGNAL(textChanged()), timer, SLOT(start()));
		connect(timer, SIGNAL(timeout()), this, SIGNAL(save()));
		connect(timer, SIGNAL(timeout()), timer, SLOT(stop()));
	}

RichTextEdit::~RichTextEdit(){}

void RichTextEdit::contextMenuEvent(QContextMenuEvent *e)
	{
		mousePressEvent(new QMouseEvent(QEvent::MouseButtonPress, e->pos(), Qt::LeftButton, Qt::LeftButton, e->modifiers()));
		QTextCursor cur = textCursor();
		if (cur.selectedText().isEmpty())
		{
			cur.select(QTextCursor::WordUnderCursor);
			setTextCursor(cur);
		}
		QMenu *menu = createStandardContextMenu(e->pos());
		menu->addSeparator();
		menu->addAction(colorPickerAction);
		menu->addSeparator()->setText("Style");
		menu->addAction(boldAction);
		menu->addAction(italicAction);
		menu->addAction(underlineAction);
		menu->addSeparator()->setText("Alignment");
		menu->addAction(leftAlignAction);
		menu->addAction(centerAlignAction);
		menu->addAction(rightAlignAction);
		menu->addAction(justifyAction);
		menu->exec(e->globalPos());
		delete menu;
	}

void RichTextEdit::changeAlignment(QAction *a)
	{
		if (a == leftAlignAction)
			setAlignment(Qt::AlignLeft);
		else if (a == centerAlignAction)
			setAlignment(Qt::AlignHCenter);
		else if (a == rightAlignAction)
			setAlignment(Qt::AlignRight);
		else if (a == justifyAction)
			setAlignment(Qt::AlignJustify);
	}

void RichTextEdit::setBold(bool x)
	{
		QTextCursor cur = textCursor();
		QTextCharFormat fmt;
		fmt.setFontWeight(!x ? QFont::Normal : QFont::Bold);
		cur.mergeCharFormat(fmt);
		setTextCursor(cur);
	}

void RichTextEdit::setFontSize(const QString &s)
	{
		setFontPointSize(s.toFloat());
	}

void RichTextEdit::setList(bool x)
	{
		QTextCursor cur = textCursor();
		if (x)
		{
			QTextListFormat listFormat;
			listFormat.setStyle(QTextListFormat::ListDisc);
			cur.createList(listFormat);
		}

		else
		{
			cur.setBlockFormat(QTextBlockFormat());
			setTextCursor(cur);
		}
	}

void RichTextEdit::setColor()
	{
		QTextCursor cur = textCursor();
		QColor color;
		if (cur.hasSelection()) color = textColor();
		else color = Qt::black;
		QColor newColor = QColorDialog::getColor(color, this);
		setTextColor(newColor);
	}

void RichTextEdit::updateCharFormat(const QTextCharFormat &fmt)
	{
		boldAction->setChecked(fmt.fontWeight()==QFont::Bold);
		italicAction->setChecked(fmt.fontItalic());
		underlineAction->setChecked(fmt.fontUnderline());
	}

void RichTextEdit::updateBlockFormat()
	{
		QTextBlockFormat fmt = textCursor().blockFormat();
		switch(fmt.alignment())
		{
			case Qt::AlignLeft:
				leftAlignAction->setChecked(true);
				break;
			case Qt::AlignHCenter:
				centerAlignAction->setChecked(true);
				break;
			case Qt::AlignRight:
				rightAlignAction->setChecked(true);
				break;
			case Qt::AlignJustify:
				justifyAction->setChecked(true);
				break;
			default:
				leftAlignAction->setChecked(true);
		}

		QTextCharFormat cf = textCursor().charFormat();
		if (cf.font().family() != fontBox->currentFont().family())
			fontBox->setCurrentFont(cf.font());
		if (cf.font().pointSize() != sizeBox->currentText().toInt())
			sizeBox->setCurrentIndex(sizeBox->findText(QString::number(cf.font().pointSize())));
	}
